package cn.com.ns.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import cn.com.ns.annotation.jdbc.Table;
public class BeanUtils {

    public static <T> T instanceClass(Class<T> clazz){
        if(!clazz.isInterface()){
            try {
                return clazz.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    
    public static <T> T instanceClass(Constructor<T> ctor, Object... args)
            throws IllegalArgumentException, InstantiationException,
            IllegalAccessException, InvocationTargetException {
        makeAccessible(ctor);
        return ctor.newInstance(args);//调用构造方法实例化
    }

    
    public static  Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes){
        try {
            return clazz.getMethod(methodName, paramTypes);
        } catch (NoSuchMethodException e) {
            return findDeclaredMethod(clazz, methodName, paramTypes);//返回共有的方法
        }
    }

    public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>[] paramTypes){
        try {
            return clazz.getDeclaredMethod(methodName, paramTypes);
        }
        catch (NoSuchMethodException ex) {
            if (clazz.getSuperclass() != null) {
                return findDeclaredMethod(clazz.getSuperclass(), methodName, paramTypes);
            }
            return null;
        }
    }

    public static Method[] findDeclaredMethods(Class<?> clazz){
        return clazz.getDeclaredMethods();
    }

    public static void makeAccessible(Constructor<?> ctor) {
        if ((!Modifier.isPublic(ctor.getModifiers())
                || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers()))
                && !ctor.isAccessible()) {
            ctor.setAccessible(true);
        }
    }

    public static Field[] findDeclaredFields(Class<?> clazz){
        return clazz.getDeclaredFields();
    }
    
    
    @SuppressWarnings("unchecked")
	public static <T> String selectOneSql(Object t,Field[] fields,Class clazz){
    	String sql = "select ";
    	String sqlWhere = " where ";
    	Map<String,Object> map = new HashMap<String,Object>();
    	map = getKeyAndValue(t);
    	for(Field field:fields){
    		sql += field.getName()+",";
    		if(map.get(field.getName())!=null){
    			sqlWhere += field.getName()+"="+map.get(field.getName())+",";
    		}
    	}
    	sql = sql.substring(0, sql.lastIndexOf(","));
    	sqlWhere = sqlWhere.substring(0,sqlWhere.lastIndexOf(","));
    	sql += " from ";
    	Class<Table> tableClass = clazz;
    	if(clazz.isAnnotationPresent(Table.class)){
    		Table table = tableClass.getAnnotation(Table.class);
    		sql += table.name();
    	}
    	sql += sqlWhere;
    	System.out.println(sql);
    	return sql;
    	
    }
    
    public static Map<String, Object> getKeyAndValue(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>();
        Class userCla = (Class) obj.getClass();
        Field[] fs = userCla.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            f.setAccessible(true); 
            Object val = new Object();
            try {
                val = f.get(obj);
                map.put(f.getName(), val);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
}
